package com.cjj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cjj.common.convention.errorcode.BaseErrorCode;
import com.cjj.common.convention.exception.ClientException;
import com.cjj.common.convention.exception.ServiceException;
import com.cjj.common.enums.OrderStatus;
import com.cjj.common.enums.OrderType;
import com.cjj.dao.entity.ServiceOrder;
import com.cjj.dao.mapper.ServiceOrderMapper;
import com.cjj.dto.req.*;
import com.cjj.service.ServiceOrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2025-10-25
 */
@Service
@RequiredArgsConstructor //构造器注入
public class ServiceOrderServiceImpl extends ServiceImpl<ServiceOrderMapper, ServiceOrder> implements ServiceOrderService {

    private final ServiceOrderMapper serviceOrderMapper;

    /**
     * 分页查询未审核订单
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public IPage<ServiceOrder> getPendingReviewOrders(Integer pageNum, Integer pageSize) {
        // 校验分页参数
        pageNum = (pageNum == null || pageNum < 1) ? 1 : pageNum;
        pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;
        pageSize = Math.min(pageSize, 100); // 限制最大页大小


        // 创建分页对象
        Page<ServiceOrder> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        LambdaQueryWrapper<ServiceOrder> wrapper = Wrappers.lambdaQuery(ServiceOrder.class)
                .eq(ServiceOrder::getStatus, OrderStatus.PENDING);

        // 直接转换并返回 IPage
        return baseMapper.selectPage(page, wrapper);
    }

    /*
     创建订单
     */
    @Transactional
    @Override
    public CreateServiceOrderDTO createOrder(CreateServiceOrderDTO createServiceOrderDTO) {
        // 1. 创建对象并保留引用
        ServiceOrder serviceOrder = BeanUtil.copyProperties(createServiceOrderDTO, ServiceOrder.class);
        // 2. 执行插入（serviceOrder会被回填）
        serviceOrderMapper.insert(serviceOrder);
        createServiceOrderDTO.setOrderId(serviceOrder.getOrderId());
        return createServiceOrderDTO;
    }

    /**
     * 分页查询当前用户订单
     * @param getOrderReqDTO
     * @return IPage<ServiceOrder>
     */
    @Override
    public IPage<ServiceOrder> getOrder(Integer pageNum, Integer pageSize,GetOrderReqDTO getOrderReqDTO) {

        // 校验分页参数
        pageNum = (pageNum == null || pageNum < 1) ? 1 : pageNum;
        pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;
        pageSize = Math.min(pageSize, 100); // 限制最大页大小

        // 创建分页对象
        Page<ServiceOrder> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        LambdaQueryWrapper<ServiceOrder> wrapper = Wrappers.lambdaQuery(ServiceOrder.class)
                .eq(ServiceOrder::getUserId, getOrderReqDTO.getUserId())
                .eq(StrUtil.isNotBlank(getOrderReqDTO.getType()),ServiceOrder::getType,getOrderReqDTO.getType())
                .eq(StrUtil.isNotBlank(getOrderReqDTO.getStatus()),ServiceOrder::getStatus,getOrderReqDTO.getStatus());


        // 直接转换并返回 IPage
        return baseMapper.selectPage(page, wrapper);
    }

    /**
     * 审核通过单个订单
     * @param orderId 订单号
     */
    @Override
    public void approveOrder(Long orderId) {
        if (orderId == null){
            throw new ClientException("订单ID不能为空");
        }
        //构建查询条件
        LambdaQueryWrapper<ServiceOrder> wrapper = Wrappers.lambdaQuery(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, orderId);
        //拿到实体
        ServiceOrder serviceOrder = baseMapper.selectOne(wrapper);

        // 空值检查
        if (serviceOrder == null) {
            throw new ServiceException("订单不存在，orderId: " + orderId);
        }

        //检查订单状态是否为待审核
        if (!serviceOrder.getStatus().equals(OrderStatus.PENDING.getValue())){
            throw new ClientException("订单当前状态不允许审批");
        }

        //修改订单状态
        serviceOrder.setStatus(OrderStatus.REVIEWED.toString());

        //更新数据库
        LambdaUpdateWrapper<ServiceOrder> updateWrapper = Wrappers.lambdaUpdate(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, orderId);

        int rows = baseMapper.update(serviceOrder, updateWrapper);
        if (rows == 0) {
            throw new ServiceException("更新订单状态失败");
        }
    }

    /**
     *审核拒绝订单
     */
    @Override
    public void rejectOrder(RejectOrderReqDTO rejectOrderReqDTO) {
        if (rejectOrderReqDTO.getOrderId() == null){
            throw new ClientException("订单ID不能为空");
        }
        //构建查询条件
        LambdaQueryWrapper<ServiceOrder> wrapper = Wrappers.lambdaQuery(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, rejectOrderReqDTO.getOrderId());
        //拿到实体
        ServiceOrder serviceOrder = baseMapper.selectOne(wrapper);

        // 空值检查
        if (serviceOrder == null) {
            throw new ServiceException("订单不存在，orderId: " + rejectOrderReqDTO.getOrderId());
        }

        //检查订单状态是否为待审核
        if (!serviceOrder.getStatus().equals(OrderStatus.PENDING.getValue())){
            throw new ClientException("订单当前状态不允许修改");
        }

        //修改订单状态
        serviceOrder.setStatus(OrderStatus.REJECTED.toString())
                .setReason(rejectOrderReqDTO.getReason());


        //更新数据库
        LambdaUpdateWrapper<ServiceOrder> updateWrapper = Wrappers.lambdaUpdate(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, rejectOrderReqDTO.getOrderId());

        int rows = baseMapper.update(serviceOrder, updateWrapper);
        if (rows == 0) {
            throw new ServiceException("更新订单状态失败");
        }
    }

    /**
     * 批量审核通过订单
     * @param batchApproveReqDTO 包含订单id列表
     */
    @Transactional
    @Override
    public void batchApproveOrders(BatchApproveReqDTO batchApproveReqDTO) {
        //获得需要审核的订单id列表
        List<Long> orderIds = batchApproveReqDTO.getOrderIds();
        // 1. 查询出所有待审核的订单
        List<ServiceOrder> orders = baseMapper.selectList(
                Wrappers.<ServiceOrder>lambdaQuery()
                        .in(ServiceOrder::getOrderId, orderIds)
                        .eq(ServiceOrder::getStatus, OrderStatus.PENDING.getValue()) // 只处理待审核的
        );

        if (orders.isEmpty()) {
            throw new ClientException("未找到待审核的订单");
        }

        // 2. 批量更新状态
        List<ServiceOrder> updateOrders = orders.stream()
                .map(order -> {
                    ServiceOrder updateOrder = new ServiceOrder();
                    updateOrder.setOrderId(order.getOrderId());
                    updateOrder.setStatus(OrderStatus.REVIEWED.getValue());
                    updateOrder.setUpdateTime(LocalDateTime.now());
                    return updateOrder;
                })
                .collect(Collectors.toList());

        // 3. 执行批量更新
        boolean success = this.updateBatchById(updateOrders);

        if (!success) {
            throw new ClientException("批量审核失败");
        }

    }

    /**
     * 批量拒绝订单
     * @param batchRejectReqDTO orderIds：订单列表； reason:拒绝原因
     */
    @Transactional
    @Override
    public void batchRejectOrders(BatchRejectReqDTO batchRejectReqDTO) {
        //获得需要审核的订单id列表
        List<Long> orderIds = batchRejectReqDTO.getOrderIds();

        LambdaUpdateWrapper<ServiceOrder> wrapper = Wrappers.lambdaUpdate(ServiceOrder.class)
                .in(ServiceOrder::getOrderId, orderIds)
                .eq(ServiceOrder::getStatus, OrderStatus.PENDING.getValue())
                .set(ServiceOrder::getStatus, OrderStatus.REJECTED.getValue())
                .set(ServiceOrder::getReason, batchRejectReqDTO.getReason()); // 直接设置值


        int updateCount = baseMapper.update(null, wrapper);

        if (updateCount == 0) {
            throw new ClientException("未找到待审核的订单");
        }

        /*// 1. 查询出所有待审核的订单
        List<ServiceOrder> orders = baseMapper.selectList(
                Wrappers.<ServiceOrder>lambdaQuery()
                        .in(ServiceOrder::getOrderId, orderIds)
                        .eq(ServiceOrder::getStatus, OrderStatus.PENDING.getValue()) // 只处理待审核的
        );

        if (orders.isEmpty()) {
            throw new ClientException("未找到待审核的订单");
        }

        // 2. 批量更新状态
        List<ServiceOrder> updateOrders = orders.stream()
                .map(order -> {
                    ServiceOrder updateOrder = new ServiceOrder();
                    updateOrder.setOrderId(order.getOrderId());
                    updateOrder.setStatus(OrderStatus.REJECTED.getValue());
                    updateOrder.setUpdateTime(LocalDateTime.now());
                    updateOrder.setReason(batchRejectReqDTO.getReason());
                    return updateOrder;
                })
                .collect(Collectors.toList());

        // 3. 执行批量更新
        boolean success = this.updateBatchById(updateOrders);

        if (!success) {
            throw new ClientException("批量拒绝失败");
        }*/
    }

    /**
     *用于跑腿服务中查询已审核的跑腿订单
     * @return 所有处于已审核状态的跑腿订单id
     */
    @Override
    public List<Long> selectReviewedRunnerOrder() {
        LambdaQueryWrapper<ServiceOrder> wrapper = Wrappers.lambdaQuery(ServiceOrder.class);

        //设置查询条件
        wrapper.select(ServiceOrder::getOrderId)  // 只查询orderId字段
                .eq(ServiceOrder::getStatus, OrderStatus.REVIEWED.getValue())
                .eq(ServiceOrder::getType, OrderType.RUNNER.getValue());

        return baseMapper.selectList(wrapper).stream()
                .map(ServiceOrder::getOrderId)
                .collect(Collectors.toList()); //流处理，提取实体中的orderId
    }

    /***
     * 修改订单状态为已接单
     * @param orderId 订单id
     */
    @Override
    public void acceptOrder(Long orderId) {
        //  查询订单信息
        ServiceOrder order = baseMapper.selectById(orderId);
        if (order == null) {
            throw new ClientException("订单不存在");
        }
        // 5. 更新订单状态
        LambdaUpdateWrapper<ServiceOrder> wrapper = Wrappers.lambdaUpdate(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, orderId)
                .eq(ServiceOrder::getStatus,OrderStatus.REVIEWED.getValue()) // 确保还是未被接单状态
                .set(ServiceOrder::getStatus, OrderStatus.ACCEPTED.getValue())
                .set(ServiceOrder::getUpdateTime, LocalDateTime.now());

        int updateCount = baseMapper.update(null, wrapper);

        if (updateCount == 0) {
            throw new ClientException("接单失败，订单可能已被其他骑手接单");
        }

    }

    /**
     * 修改订单状态为已完成
     * @param orderId 订单id
     */
    @Override
    public void completedOrder(Long orderId) {
        Wrapper<ServiceOrder> wrapper = Wrappers.<ServiceOrder>lambdaUpdate(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, orderId)
                .set(ServiceOrder::getStatus, OrderStatus.COMPLETED.getValue());

        //更新数据库
        int updateCount = baseMapper.update(null, wrapper);
        if (updateCount == 0) {
            throw new ServiceException(BaseErrorCode.SERVICE_ERROR);
        }
    }

    /**
     * 用户取消订单
     * @param canceledOrderReqDTO：userId,orderId
     */
    @Override
    public void canceledOrder(CanceledOrderReqDTO canceledOrderReqDTO) {

        //构造查询条件
        LambdaQueryWrapper<ServiceOrder> orderLambdaQueryWrapper = Wrappers.lambdaQuery(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, canceledOrderReqDTO.getOrderId())
                .eq(ServiceOrder::getUserId, canceledOrderReqDTO.getUserId());

        //查询数据库
        ServiceOrder serviceOrder = baseMapper.selectOne(orderLambdaQueryWrapper);
        if (serviceOrder == null) {
            throw new ServiceException(BaseErrorCode.SERVICE_ERROR);
        }

        //检查订单是否是已完成
        if (serviceOrder.getStatus().equals(OrderStatus.COMPLETED.getValue())) {
            throw new ClientException("订单已完成");
        }

        //检查订单是否是已取消
        if (serviceOrder.getStatus().equals(OrderStatus.CANCELED.getValue())) {
            throw new ClientException("订单已取消");
        }

        serviceOrder.setStatus(OrderStatus.CANCELED.getValue());
        baseMapper.updateById(serviceOrder);

    }

    /**
     *购买订单
     * 在订单表中填写购买者id
     */
    @Override
    public void purchaseOrder(PurchaseOrderReqDTO purchaseOrderReqDTO) {
        if (purchaseOrderReqDTO.getOrderId() == null) {
            throw new ClientException("未上传订单id");
        }
        if (purchaseOrderReqDTO.getCustomerId() == null){
            throw new ClientException("未上传顾客id");
        }
        LambdaQueryWrapper<ServiceOrder> orderLambdaQueryWrapper = Wrappers.lambdaQuery(ServiceOrder.class)
                .eq(ServiceOrder::getOrderId, purchaseOrderReqDTO.getOrderId());
        ServiceOrder serviceOrder = baseMapper.selectOne(orderLambdaQueryWrapper);
        if (serviceOrder == null) {
            throw new ServiceException(BaseErrorCode.SERVICE_ERROR);
        }
        if (serviceOrder.getCustomerId() != null){
            throw new ClientException("订单已购买");
        }
        if (!serviceOrder.getStatus().equals(OrderStatus.REVIEWED.getValue())){
            throw new ServiceException("订单状态异常");
        }
        //将购买者id填入表中
        serviceOrder.setCustomerId(purchaseOrderReqDTO.getCustomerId());
        baseMapper.updateById(serviceOrder);
    }

    /**
     * 分页查询当前用户购买的点单
     * @param getPurchaseOrderReqDto 包含用户id，订单类型
     * @return IPage<ServiceOrder>
     */
    @Override
    public IPage<ServiceOrder> getPurchaseOrders(Integer pageNum,Integer pageSize,GetPurchaseOrderReqDto getPurchaseOrderReqDto) {


        // 校验分页参数
        pageNum = (pageNum == null || pageNum < 1) ? 1 : pageNum;
        pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;
        pageSize = Math.min(pageSize, 100); // 限制最大页大小

        // 创建分页对象
        Page<ServiceOrder> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        LambdaQueryWrapper<ServiceOrder> wrapper = Wrappers.lambdaQuery(ServiceOrder.class)
                .eq(StrUtil.isNotBlank(getPurchaseOrderReqDto.getUserId().toString()),ServiceOrder::getCustomerId, getPurchaseOrderReqDto.getUserId())
                .eq(StrUtil.isNotBlank(getPurchaseOrderReqDto.getType()),ServiceOrder::getType,getPurchaseOrderReqDto.getType());

        // 直接转换并返回 IPage
        return baseMapper.selectPage(page, wrapper);
    }


}
